home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-08-10 | 25.1 KB | 524 lines | [TEXT/CWIE] |
- /* GDOpenWindow.c
- Copyright © 1989-1997 Denis G. Pelli, David H. Brainard
-
- EXAMPLE:
-
- Open your window by saying:
- window=GDOpenWindow(device);
- Show it by saying:
- ShowWindow((WindowPtr)window);
- When you're through with the window, get rid of it by calling:
- GDDisposeWindow(window);
- Besides closing the window and disposing of the allocated memory structures
- GDDisposeWindow also restores the device's color table and clut.
-
- SUMMARY:
-
- window=GDOpenWindow(device) opens a full-screen window on the specified screen,
- calls GDGrayColorTable(device) which gives the device a standard gray color table,
- and calls AddExplicitPalette(window), which allows you
- to specify colors to paint with by using PmForeColor() and PmBackColor(). The
- window truly fills the screen: any rounded corners are made square and if the
- window is on the main screen then the Menu Bar is hidden. The screen occupies
- the content area of the window; the window's frame (one-pixel black line border
- and title bar) is off that screen, but will appear on other screens that form
- contiguous parts of your desktop. The elegant solution to this, which perhaps
- someone will implement, would be to define a new window type that has no frame.
-
- GDDisposeWindow(window) closes and discards a color window, disposing of any
- palette or color table, restoring the screen, generally undoing whatever GDOpenWindow1 did.
-
- AddExplicitPalette(window) adds a palette to a color window or GWorld with all
- the colors marked as pmExplicit. This allows you to use PmForeColor() and
- PmBackColor() to specify the value you want poked into each pixel by QuickDraw
- operations, e.g. EraseRect() and DrawString().
-
- RemovePalette(window) disposes of the palette created by AddExplicitPalette.
-
- SwapWindowExplicitMode(window,&isExplicit) swaps the contents of the Boolean
- argument with the "explicit" bit (bit 14 of the ctFlags field) in the color
- table. The use of this bit is documented in
- <http://rajsky.psych.nyu.edu/VideoToolbox/VideoNotes/CopyBitsTip.html>.
- After much experimentation I decided that it's not useful, but I
- leave this routine here for others that wish to experiment. Note that when
- GDOpenWindow() creates a window, the window shares the color table belonging to
- the device, so calling SwapWindowExplicitMode() modifies the shared table, i.e.
- the device's color table is modified. You should restore it by calling
- MakeColorTableExplicit() again. Failing to restore it will have cosmetic
- aftereffects, even after your application quits. The most obvious aftereffect is
- that documents in Word will be largely gray.
-
- GetBitMapPtr(window) returns a pointer to the window's bitmap or pixmap.
-
- IsGWorldPtr(window) returns true only if the window is a GWorldPtr.
-
- COMMENTS:
-
- Please read <http://rajsky.psych.nyu.edu/VideoToolbox/VideoNotes/CopyBitsTip.html>.
- QuickDraw likes to
- pick a bunch of good colors and stuff them in the clut, in essentially random
- order, except that white is first and black is last. It wants you to specify any
- desired color as an RGB triplet and then it picks the mysterious clut index that
- would provide the closest match. If you're processing grayscale images, then
- QuickDraw's approach involves a lot of overhead involving inverse color tables,
- and makes the numbers stored in your pixels meaningless (unless you look them up
- in the associated color table or palette).
-
- The philosophy of the VideoToolbox is to bypass QuickDraw's color model, and
- work explicitly with the numbers that are stored in your pixels.
- SetPixelsQuickly will efficiently poke (or peek) the numbers in your PixMap.
- However, if you want to use QuickDraw's handy drawing operations, especially
- EraseRect() and DrawString() then you need a way to specify the foreground and
- background colors. AddExplicitPalette() gives your window a palette in which all
- the colors are marked as pmExplicit. This tells the palette manager to use your
- arguments to PmForeColor() and PmBackColor() literally.
-
- I suggest that you control the clut by calling GDUncorrectedGamma() and
- GDSetEntries(), since these calls directly control the video device driver,
- bypassing the Color Manager. Since the Color and Palette Managers don't know
- that you've changed the color environment they can't react to it, and will
- passively let you continue to specify colors by their clut index. For example,
- the Palette Manager religiously believes that the first clut entry should be
- white and the last one black, and it will change them back to those values if
- you change them and it finds out about it. If you use the Color Manager
- SetEntries call then the Paletter Manger WILL find out because a record is made
- in the ColorTable. Calling GDSetEntries() bypasses the Color Manager. Instead,
- the video device driver writes directly to the clut and the ColorTable is not
- modified. Of course, this means that you should ignore the ColorTable since it
- will no longer reflect the contents of the clut.
-
- Every time you access the stdio package, e.g. printf or getch(), THINK C will
- move the console window to the front, which may obscure your window. You can
- bring your window back to the front by calling BringToFront() or SelectWindwo().
-
- NOTE:
- Tom Busey (busey@indiana.edu) writes: "I'm using an 8-bit SuperMac ColorCard
- that a used computer dealer gave me when I ordered a Toby card. I discovered
- that the status and control calls for GDUncorrectedGamma return -17 and -18
- respectively, which means that the driver doesn't support different gammas.
- GDUncorrectedGamma returns an error message, but GDOpenWindow doesn't use the
- error message or pass it back to the calling program. I'm wondering if there are
- people using GDOpenWindow who think that they are getting a linear gamma but who
- are actually getting an error message and not learning about it."
- Tom's facts are right, but he needn't worry. A few video drivers, e.g.
- Radius PowerView, and apparently the SuperMac ColorCard, don't implement gamma
- tables at all, but the error from GDUncorrectedGamma is probably not a concern.
- The real test is to run TimeVideo. TimeVideo does a write-and-read-back test of
- the clut of your video card. If that test passes then you can safely conclude
- that there's no gamma translation going on. So, as nearly every document in the
- VideoToolbox says: run TimeVideo and read the report.
- Here's how gamma tables work. According to the Apple manual (Designing
- Cards and Drivers), the values in the rgb triplets that you supply in a
- cscSetEntries call to the video driver are first translated via the gamma table
- (each r,g, and b component separately) before being loaded into the CLUT
- hardware table. Most drivers maintain a gamma table internally (in computer
- memory) and allow you to get and set it via the GDGetGamma and GDSetGamma calls.
- A few video drivers (Radius PowerView, SuperMac ColorCard) don't support gamma
- tables. They load your rgb values directly into the CLUT, without translation.
- However, for users of the VideoToolbox that's usually fine, since that's exactly
- the behavior that we routinely request by calling GDUncorrectedGamma. Of course,
- if you want to load a custom gamma table, other than the identity
- transformation, then you'll be calling GDSetGamma, and you should make sure it
- does not return an error. (Alas, the Radius PowerView driver more or less
- ignores the set- and get-gamma requests--GDGetGamma returns a table that's all
- zeroes--but the driver fails to report an error. I wrote to the Radius
- programmer a year ago, but they're no longer interested in working on that
- product.)
-
-
- PROBLEM:
- How can I tell whether I've got a CGrafPtr or a GWorldPtr? (In one case I'll call
- GetGWorldDevice, in the other case I'll get max device.) I noticed that the
- portVersions are 0xc001 and 0xc000. Should I use that to tell?
-
- ANSWER FROM APPLE DEVSUPPORT (8/93):
- You can use GetGWorldDevice() on GWorldPtr, GrafPort or CGrafPort. Use
- TestDeviceAttibute() to test if the returned GDHandle is a "real" screen or not.
-
- Also, you should refer to the tech note “RowBytes Revealed II” (available on the
- June Developer CD) which states:
-
- You'll notice in Figure 1 that the portVersion field of a cGrafPort coincides
- with the location of the rowBytes field of a grafPort. Remember, a cGrafPort has
- the same size as a grafPort. During debugging, you can use the same information
- that CopyBits uses to identify cGrafPorts.
-
- If you use a grafPort template to display memory for an unknown grafPort, you
- can tell if it is a cGrafPort because the rowBytes will be equal to 0xC000. The
- 0xC corresponds to the two high bits being set in the portVersion field of a
- cGrafPort. Since these bits can not be set in a grafPort, you know you have a
- cGrafPort. In addition, if the bottom bit of the portVersion field is set, then
- it is a gWorld. Thus, if your rowBytes field has a value of 0xC001, then you
- know you have a gWorld.
-
- CONCLUSION:
- This advice is implemented in the routine IsGWorldPtr(window).
-
- REFERENCES:
- http://devworld.apple.com/dev/technotes/tn/tn1024.html
- http://devworld.apple.com/dev/techsupport/source/code/Snippets/QuickDraw/Restore_Screen_Cluts/ReadMe.html
-
- HISTORY:
-
- 12/88 dgp wrote it
- 8/5/89 added call to GDUncorrectedGamma, so I couldn't forget.
- 8/15/89 dgp trivia
- 3/20/90 dgp make compatible with MPW C.
- 3/29/90 dgp changed declared returned type from WindowPtr to CWindowPtr, which
- is what it's really been all along. Same change to argument of
- GDDisposeWindow(). The new offscreen GWorld calls for the first time
- make it easier to honestly declare one's windows as color rather
- than pretending they're not.
- 8/24/91 dgp Made compatible with THINK C 5.0.
- 2/1/92 dgp Made optional the device argument to GDDisposeWindow(). If it's
- NULL, then it will be determined automatically from window.
- 2/3/93 dhb Extracted AddExplicitPalette from GDOpenWindow.
- 2/21/93 dgp HideMenuBar if window is on main screen.
- 2/23/93 dgp AddExplicitPalette() returns immediately unless it receives a color
- window.
- Added GDOpenWindow1() and GDDisposeWindow1(), which both use
- a WindowPtr, instead of a less convenient CWindowPtr.
- 3/5/93 dgp Added calls to UnclipScreen() and RestoreScreenClipping(), so the window
- now truly fills the whole screen. Edited GDOpenWindow() for clarity.
- 3/7/83 dgp Added calls to GDSaveGamma(device) and GDRestoreGamma(device).
- 4/16/93 dgp Cosmetic editing.
- 5/22/93 dgp Added RemovePalette(), but didn't test it.
- 1/27/94 dgp Cosmetic editing.
- 3/5/94 dgp Decided that RemovePalette() works fine now.
- 6/8/94 dgp AddExplicitPalette now calls the new MakeColorTableExplicit(), which
- sets the Color Table ctFlags to indicate that the Color Table refers
- explicitly to the explicit palette. This tells CopyBits to treat
- the pixels as numbers, not indices.
- 6/13/94 dgp In response to query by David Brainard, I now document above
- the obscure fact that GDOpenWindow's frame will appear on
- other screens that are contiguous parts of the desktop.
- 8/11/94 dhb & dgp David Brainard discovered that MakeColorTableExplicit(), which
- is called by AddExplicitPalette, which is called by GDOpenWindow1, was affecting
- not just the new window's color table, but was also affecting the device's color
- table (because they share the same color table), and that the device's color
- table was not restored. "The symptom is that if you subsequently launch
- Microsoft Word, the background of the text window takes on a strange color
- (grey) in regions where there is text," and the problem persists until reboot.
- The solution is to give our window its own color table, which we can
- safely modify.
- 8/12/94 dhb & dgp on 8/11 denis inadvertently introduced a bug into GDDisposeWindow1,
- moving the call to GetWindowDevice() to a point after the window
- was disposed of. David fixed it, moving the call back where it belonged.
- 8/14/94 dgp GDOpenWindow1 now gets the color table from the window's device instead
- of the main device.
- 8/17/94 dgp make color table NOT explicit when GDDisposeWindow1 is called.
- 9/5/94 dgp removed assumption in printf's that int==short.
- 10/10/94 dgp GDOpenWindow1 now associates correct device's color table with window,
- not MainDevice's.
- 10/24/94 dgp GDOpenWindow1 returns NULL if there's no driver associated with the device.
- 10/25/94 dgp Added GDGrayColorTable(device), which gives the device a standard gray color table.
- 11/2/94 dgp Leave the explicit bit alone. For the adventurous I provide the
- MakeColorTableExplicit() routine and documentation in
- <http://rajsky.psych.nyu.edu/VideoToolbox/VideoNotes/CopyBitsTip.html>
- 11/17/94 dgp renamed IsWindow to IsGrafPtr. Renamed IsOffScreen to IsGWorldPtr.
- 4/11/95 dgp Fixed assertion failure in GDGrayWindow; the rsrc id of the 2-bit gray ramp is 2,
- not 32+2.
- 4/11/95 dgp transferred some documentation of IsGWorldPtr from GetScreenDevice.c to above.
- 3/8/95 dgp GDOpenWindow1()'s call to GDGrayColorTable() causes the
- window frame to become orange. I don't understand why, but it's only a cosmetic bug,
- so i'm ignoring it for the moment.
- 10/23/96 dhb Added code to set the entries in the explicit palette added by AddExplicitPalette().
- This is doing the same thing that the MAKE_COLOR_TABLE conditional was trying to do,
- but it seems to work. I got the example (sort of) out of the Advanced Color Imaging
- manual, p. 1-26. A brief test indicates that the new code makes things work properly in
- 32-bit mode and doesn't break them in 8-bit mode.
- 10/28/96 dhb Fixed bug introduced by 10/23/96 change. With MAKE_COLOR_TABLE set to 2, the screen did
- not restore properly on exit. I changed code to create a new color table in mode 2 as well
- as in mode 1. This seems to allow the proper restore on close.
- 11/14/96 dgp renamed argument of SwapWindowExplicitMode from "explicit" to "isExplicit" to
- avoid conflict with the C++ reserved word "explicit". Thanks to Eric Fredericksen,
- eric@mach2.hipl.uci.edu for alerting me to the problem and solution.
- 12/18/96 dhb Modified MAKE_COLOR_TABLE==2 code to only operate if pixelSize>8. This makes
- the behavior the same as the old default for less than 8 bits/pixel but like
- the new code for more than 8 bits/pixel. I did this because the new method
- introduced a subtle bug in 8 bit/pixel mode, wherein when you wrote 0 to
- the frame buffer through the various draw routines the value was sent as 255.
- 12/18/96 dgp Changed i<<8, which assumes 8-bit DAC, to (i<<8)+i which works for any DAC size.
- 12/18/96 dgp Eliminated the old MAKE_COLOR_TABLE==1 mode, which no one ever used, reducing the
- choice to false (i.e. 0), the old, pre 10/96 code, and true (i.e. 1), for
- David's new code, which makes a color table only for more-than-8-bit pixels.
- 1/20/97 dgp Generalized GDGrayColorTable to become GDStandardColorTable.
- 1/20/97 dgp Fixed long-standing bug in GDDisposeWindow: it failed to restore the CLUT. It
- now calls GDStandardColorTable and GDRestoreDeviceCLUT, to restore a standard
- color table, and following the helpful RestoreColorSlam.c snippet by Apple's
- Forrest Tanaka (see REFERENCES, above), we call DrawBehind() to redraw the
- screen in the new color table.
- 2/1/97 dgp GDDisposeWindow now is more successful at restoring the screen. I changed
- PaintBehind(NULL,GetGrayRgn()) to PaintBehind(FirstWindow(),rgn). Previously
- the front window wasn't getting updated; now it is. Replacing GetGrayRgn()
- by rgn (the structure region of the window we're closing) restricts the update
- to just the affected screen, which makes the update faster and less visually
- distracting when there are multiple screens.
- 2/2/97 dgp Cleaned up the allocation and disposal of the rgn mentioned immediately above.
- 2/2/97 dgp GDOpenWindow now calls RestoreDeviceClut to actually copy the new color table
- into the device's CLUT. And we call SelectWindow on our new window to make the
- Palette Manager aware. As a result, GDOpenWindow now seems to correctly
- leave us with a grayscale clut, and a window whose palette matches that clut.
- 3/26/97 dgp Fixed bug in IsGWorldPtr(). It was testing whether 3 bits were on, whereas it
- ought to have been testing that the value of the word was 0xc001, i.e. also making
- sure that the rest of the bits were zero. This may have been responsible
- for some mysterious crashes of 68K code.
- 3/26/97 dgp Added window!=NULL test to both IsGWorldPtr and IsGrafPtr.
- 3/27/97 dgp Added (unsigned short) to IsGWorldPtr for correct comparison.
- 3/29/97 dgp Following advice of Inside Mac, GDOpenWindow now leaves new window invisible.
- User must call ShowWindow to reveal it.
- 5/19/97 dgp Added URLs to documents now in website VideoNotes folder.
- 8/10/97 dgp Fixed crashing bug reported and diagnosed by Tilman Vogel, tilman.vogel@uni-tuebingen.de.
- We were using slightly different criteria in AddExplicitPallette (to allocate)
- and GDDisposeWindow (to free) a color table. He discovered that if the main
- screen was set to more than 8 bits and the screen being opened and closed was
- at 8 bits, then the color table wasn't allocated (correct), but the code
- erroneously attempted to dispose of it, which led to a crash. Now we always
- get the pixel size from the GetWindowDevice(window), rather than through
- the window's pmTable (which reflects the main device, not the window per se).
- KNOWN BUGS:
- 2/2/97 dgp The window created by GDOpenWindow fills the screen of the specified device, but
- has a one-pixel frame and a title bar that are just off that screen, and will appear on the
- edges of other screens that are logically adjacent on the desktop. I think this could be
- fixed by defining a new window type that had no frame.
- 2/2/97 dgp We never update the window. If you move another window in front of it, and then
- move ours back to front, there will be a big white footprint where the other window used to
- be. Fixing this would require saving a copy (at all times?) of our window in an offscreen
- GWorld and copying from there to restore any invalidated part when our window receives
- at update event. (At present we ask the OS not to pass any update events to our window.)
- */
- #include "VideoToolbox.h"
-
- // Set MAKE_COLOR_TABLE to 0 (i.e. false) to generate the old code, pre 10/96, that only
- // supports up-to-8-bit pixels. Set it to 1 (i.e. true) to get DHB's enhanced version of
- // the color table code that supports all pixels sizes. See 10/23/96, 10/28/96 history
- // comments above. We suggest you leave it set to 1 unless you discover
- // that this causes a problem with large pixels that you didn't formerly have.
- // If you do find a problem, please let us know: denis@cns.nyu.edu, brainard@psych.ucsb.edu
- #define MAKE_COLOR_TABLE 1
-
- void GDStandardColorTable(GDHandle device,Boolean isColor); // This can be deleted once VideoToolbox.h is precompiled anew.
-
- WindowPtr GDOpenWindow1(GDHandle device)
- {
- return (WindowPtr)GDOpenWindow(device);
- }
-
- void GDDisposeWindow1(WindowPtr window)
- {
- GDDisposeWindow((CWindowPtr) window);
- }
-
- CWindowPtr GDOpenWindow(GDHandle device)
- {
- CWindowPtr window;
- Rect r;
- GDHandle oldDevice;
-
- if(device==NULL || (*device)->gdRefNum==0)return NULL;
- r=(*device)->gdRect; // rect of desired screen in global coordinates
- GDSaveGamma(device);
- GDUncorrectedGamma(device);
- UnclipScreen(device);
- GDGrayColorTable(device);
- oldDevice=GetGDevice();
- SetGDevice(GetMainDevice()); // Needed for window to work properly.
- window=(CWindowPtr)NewCWindow(NULL,&r,"\p",FALSE,plainDBox,(WindowPtr) -1L,0,123L);
- (*window->portPixMap)->pmTable=(**(**device).gdPMap).pmTable;
- SetGDevice(oldDevice);
- AddExplicitPalette((WindowPtr)window);
- RestoreDeviceClut(device); // Copy new color table into CLUT
- SelectWindow((WindowPtr)window);
- return window;
- }
-
- void GDGrayColorTable(GDHandle device)
- // Give the device a standard gray-ramp color table, appropriate to its pixelSize
- {
- GDStandardColorTable(device,0);
- }
-
- void GDStandardColorTable(GDHandle device,Boolean isColor)
- // Give the device a standard color (if isColor) or grayscale (if !isColor) color table,
- // appropriate to its pixelSize
- {
- ColorTable **table;
- PixMap **pm;
- int id;
-
- if(device==NULL)return;
- pm=(**device).gdPMap;
- table=(**pm).pmTable;
- id=(**pm).pixelSize;
- // As explained in Advanced Color Imaging, +64 requests a color table with the hilight color.
- if(isColor)id+=64; // color
- else id+=32; // grayscale
- if((**device).gdType==clutType && (**table).ctSeed!=id){
- table=GetCTable(id);
- assert(table!=NULL);
- assert((**(**pm).pmTable).ctSize==(**table).ctSize);
- memcpy(*(**pm).pmTable,*table,8+((**table).ctSize+1)*sizeof(ColorSpec));
- DisposeCTable(table);
- table=(**pm).pmTable;
- (**table).ctFlags|=0x8000; // mark as belonging to a device
- GDeviceChanged(device);
- }
- }
-
- void GDDisposeWindow(CWindowPtr window)
- // Dispose of window and palette and restore the screen's clut and clipping.
- {
- GDHandle device;
- Boolean isColor;
- Region **rgn;
-
- if(window==NULL)return;
- RemovePalette((WindowPtr)window);
- device=GetWindowDevice((WindowPtr)window);
- if(device!=NULL){
- // Restore CLUT before closing window, so screen update will look right
- GDRestoreGamma(device); // restore original gamma table
- isColor=TestDeviceAttribute(device,gdDevType);
- GDStandardColorTable(device,isColor); // install standard color table
- GDRestoreDeviceClut(device); // copy color table into CLUT
- }
- #if MAKE_COLOR_TABLE
- if((**(**device).gdPMap).pixelSize>8)
- DisposeHandle((Handle)(*((CGrafPtr)window)->portPixMap)->pmTable);
- #endif
- DisposeWindow((WindowPtr)window);
- if(device!=NULL){
- RestoreScreenClipping(device); // calls DrawMenuBar().
- rgn=NewRgn();
- RectRgn(rgn,&(*device)->gdRect); // rect of screen in global coordinates
- PaintBehind(FrontWindow(),rgn); // redraw that screen with new color tables
- DisposeRgn(rgn);
- }
- }
-
- void AddExplicitPalette(WindowPtr window)
- // Create a palette for the color window and mark all the entries as explicit.
- // Copy the entries from the window's device.
- {
- GDHandle device;
- CTabHandle ct;
- PaletteHandle palette;
- int colors;
- int pixelSize;
- #if MAKE_COLOR_TABLE
- int i,error;
- RGBColor color;
- #endif
-
- if(window==NULL)return;
- if(((CGrafPtr)window)->portVersion>=0) return; // Not a color window, return.
- device=GetWindowDevice(window);
- if(device==NULL)PrintfExit(
- "AddExplicitPalette: window has no device! %s line %d.\n",__FILE__,__LINE__);
- ct=(**(**device).gdPMap).pmTable;
- colors=(*ct)->ctSize+1;
- pixelSize = (**(**device).gdPMap).pixelSize;
- #if MAKE_COLOR_TABLE
- if (pixelSize>8) {
- error=HandToHand((Handle *)&ct);
- if(error)PrintfExit("%s line %d: error %d in copying color table\n"
- ,__FILE__,__LINE__,error);
- (*ct)->ctFlags &= 0x7fff; // clear "device" bit
- for(i=0;i<colors;i++) (*ct)->ctTable[i].value=i;
- (*ct)->ctSeed=GetCTSeed();
- (*((CGrafPtr)window)->portPixMap)->pmTable=ct;
- }
- #endif
- palette=NewPalette(colors,ct,pmExplicit+pmTolerant,0);
- #if MAKE_COLOR_TABLE
- if (pixelSize>8) {
- for (i = 0; i<colors; i++) {
- color.red = color.green = color.blue = (i<<8)+i;
- SetEntryColor(palette,i,&color);
- }
- }
- #endif
- SetPalette(window,palette,0);
- }
-
- /*
- RemovePalette may look dangerous, but it isn't. I worried that the Window or
- Palette Manager might become confused if it later tries to access the
- window's palette, which no longer exists. However, by trial and error
- I've found that this works fine, and that my attempts to make explicit the
- fact that the palette is gone, e.g. by calling SetPalette(window,NULL,0),
- all produced crashes. I conclude that the Palette or Window Manager monitors
- the calls to DisposePalette and thus knows that the palette is gone.
- */
- void RemovePalette(WindowPtr window)
- {
- if(window==NULL)return;
- DisposePalette(GetPalette(window));
- }
-
- void SwapWindowExplicitMode(CWindowPtr window,Boolean *isExplicit)
- // Get and set bit 14 of the ctFlags field of the window's color table.
- // This is only relevant to a CopyBits from an offscreen
- // graphics environment, be it PixMap or GWorld, to an onscreen window.
- // See Inside Mac VI, page 20-17. To get the full story see
- // <http://rajsky.psych.nyu.edu/VideoToolbox/VideoNotes/CopyBitsTip.html>
- {
- int i,ok;
- ColorTable **ct;
- Boolean oldIsExplicit;
-
- if(window==NULL)return;
- // If it's a GWorldPtr then we must lock the pixels to access the pixmap.
- if((window->portVersion&0xc001)==0xc001){
- ok=LockPixels(GetGWorldPixMap(window));
- if(!ok)return;
- }
- ct=(*window->portPixMap)->pmTable;
- oldIsExplicit=((*ct)->ctFlags&0x4000)!=0;
- if(*isExplicit){
- (*ct)->ctFlags|=0x4000;
- for(i=(*ct)->ctSize;i>=0;i--)(*ct)->ctTable[i].value=i;
- }else{
- (*ct)->ctFlags&=~0x4000;
- }
- *isExplicit=oldIsExplicit;
- }
-
- // CAUTION: The PixMap handles are not locked. So don't move memory. The
- // returned pointers will become invalid as soon as you call any routine
- // that moves memory. CopyBits and CopyBitsQuickly are ok.
- BitMap *GetBitMapPtr(CWindowPtr window)
- {
- BitMap *bits;
- int ok;
- PixMapPtr *pm;
-
- if(IsGWorldPtr(window)){
- // It's a GWorldPtr, lock the pixels, return pixmap ptr.
- ok=LockPixels(GetGWorldPixMap((GWorldPtr)window));
- if(!ok)return NULL;
- pm=GetGWorldPixMap((GWorldPtr)window);
- // HLock((Handle)pm);
- bits = (BitMap *)*pm;
- }else if(!IsGrafPtr(window)){
- pm=window->portPixMap;
- // HLock((Handle)pm);
- bits = (BitMap *)*pm;
- }else{
- bits = &((WindowPtr)window)->portBits;
- }
- return bits;
- }
-
- Boolean IsGWorldPtr(CWindowPtr window) // Is it a GWorldPtr?
- {
- return window!=NULL && (unsigned short)window->portVersion==(unsigned short)0xc001;
- }
-
-
- Boolean IsGrafPtr(CWindowPtr window) // Is it a WindowPtr?
- {
- return window!=NULL && window->portVersion>=0;
- }
-
-